package path.calculator;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class RecursivePermutationGenerator {
    private final int numberOfNodes;

    public RecursivePermutationGenerator(int numberOfNodes) {
        this.numberOfNodes = numberOfNodes;
    }

    public List<String> allPermutations() {
        List<Character> nodes = new ArrayList<Character>(numberOfNodes);
        for (int i = 0; i < numberOfNodes; ++i)
            nodes.add((char) ('a' + i));

        return generatePermutation(new LinkedList<String>(), nodes);
    }

    private List<String> generatePermutation(List<String> result, List<Character> nodes) {
        if (nodes.size() == 1) {
            List<String> seed = new LinkedList<String>();
            seed.add("" + nodes.get(0));
            return seed;
        }

        for (int nodeIndex = nodes.size() - 1; nodeIndex >= 0; --nodeIndex) {
            Character c = nodes.get(nodeIndex);
            List<Character> nodesMinusCurrent = new ArrayList<Character>(nodes);
            nodesMinusCurrent.remove(c);
            List<String> allSubCombinations = generatePermutation(result, nodesMinusCurrent);

            int currentLength = allSubCombinations.size();
            for (String current : allSubCombinations) {
                for (int index = 0; index <= currentLength; ++index) {
                    String newCombination = String.format("%s%c%s", before(index, current), c,
                            after(index, current));
                    result.add(newCombination);
                }
            }
        }
        return result;
    }

    private String before(int index, String current) {
        return current.substring(0, index);
    }

    private String after(int index, String current) {
        int length = current.length();
        if (index == length)
            return "";

        return current.substring(index, length);
    }
}